package org.lh.ibernate.core.impl;

import org.lh.ibernate.annotation.Column;
import org.lh.ibernate.annotation.Id;
import org.lh.ibernate.annotation.Table;
import org.lh.ibernate.cache.Tools.JedisTools;
import org.lh.ibernate.cache.impl.JedisFactory;
import org.lh.ibernate.core.ICacheHandle;
import org.lh.ibernate.core.IFieldHandle;
import org.lh.ibernate.core.IQuery;
import org.lh.ibernate.core.IResultSetHandler;
import org.lh.ibernate.core.tools.ParameterLink;
import org.lh.ibernate.utils.IDbUtil;
import org.lh.ibernate.utils.impl.DbUtil;
import redis.clients.jedis.Jedis;
import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

import static org.lh.ibernate.common.CommonUtil.printSql;

public class QueryUtil<T,PK>  implements IQuery<T,PK> {

    private IFieldHandle iFieldHandle=new FieldHandle();
    private IResultSetHandler iResultSetHandler;
    private ICacheHandle iCacheHandle;
    private IDbUtil iDbUtil=new DbUtil();
    private Object currentObj;
    private String pkName=new String();
    private Object resultObj=new Object();
    private Object pkValue=new Object();
    private volatile String tableName=new String();  //本地变量和主存同步
    private ParameterLink parameterLink=new ParameterLink();
    //缓存查找
    @Override
    public  T findObjFromRedis(PK pk){
        Jedis jedis=JedisFactory.getJedisConn();
        JedisTools jedisTools=new JedisTools(jedis);
        Object obj=jedisTools.get(String.valueOf(pk));
        jedisTools.freeJedisConn(jedis);
        if(obj!=null){
            Logger logger=Logger.getLogger("Ibernate: redis"+new Date());
            logger.info("Ibernate: redis obj"+obj);
            System.out.println("this is "+obj);
            jedisTools.freeJedisConn(jedis);
            return (T) obj;
        }
        return null;
    }


    public T saveObjToRedis(PK pk,T obj){
        Jedis jedis=JedisFactory.getJedisConn();
        JedisTools jedisTools=new JedisTools(jedis);
        jedisTools.set(String.valueOf(pk), (String) obj);
        jedisTools.freeJedisConn(jedis);
        return obj;
    }

    //主键查询
    @Override
    public T findOneObjBySql(Class<T> clazz,PK pk) throws Exception {
        StringBuffer sql=new StringBuffer("select * from ");
        Table annoTableName = (Table) clazz.getAnnotation(Table.class);
        tableName = annoTableName.name(); //获取表名称
        sql.append(tableName);
        Field[] fields=clazz.getDeclaredFields();
        for (Field fieldItem : fields) {
            if(fieldItem.isAnnotationPresent(Id.class)){
                Column column=fieldItem.getAnnotation(Column.class);
                pkName=column.value();
                break;
            }
        }
        sql.append(" where "+pkName+"=?");
        printSql(new String(sql));  //输出语句
        DbUtil dbUtil=new DbUtil();
        ResultSet resultSet=dbUtil.query(new String(sql),parameterLinkHandle(pk));
        clearParameterLink(); //释放内存
        iResultSetHandler=new ResultSetHandler(clazz);
        resultObj=iResultSetHandler.handle(resultSet);
        return (T) resultObj;
    }

    /*
    *
    * @author idea
    * @date 2018/7/11
    * @param []
    * @return org.lh.ibernate.core.tools.ParameterLink
    * @des 由于架构设计问题，需要创建一个参数链对象来进行赋值
    */
    private ParameterLink parameterLinkHandle(PK pk){
        List<Object> paramsList=new ArrayList<Object>();
        paramsList.add(pk);
        parameterLink.setParamList(paramsList);
        return parameterLink;
    }

    private void clearParameterLink(){
        parameterLink.clear();
    }


    //全部查询
    @Override
    public List<T> findAllBySql(Class<T> clazz) throws Exception {
        StringBuffer sql=new StringBuffer("select * from ");
        Object resultObj=new Object();
        boolean tableNameExist=clazz.isAnnotationPresent(Table.class);
        if(tableNameExist) {
            Object pkValue = new Object();
            String pkName = new String();
            Table annoTableName = (Table) clazz.getAnnotation(Table.class);
            String tableName = annoTableName.name(); //获取表名称
            sql.append(tableName);
        }
        printSql(new String(sql));
        DbUtil dbUtil=new DbUtil();
        ResultSet resultSet=iDbUtil.query(new String(sql));
        iResultSetHandler=new ResultSetHandler(clazz);
        List<T> resultList= (List<T>) iResultSetHandler.handleList(resultSet);
        return resultList;
    }


    //自定义的sql查询方法，可以包含有多个参数
    @Override
    public List<T> queryCustom(String sql, ParameterLink parameterLink, Class clazz) throws Exception {
        DbUtil db=new DbUtil();
        ResultSet resultSet=db.query(sql,parameterLink);
        IResultSetHandler resultSetHandler=new ResultSetHandler(clazz);
        List<T> resultList= (List<T>) resultSetHandler.handleList(resultSet);
        return resultList;
    }


    @Override
    public  List<T>  queryCallHandle(String callSql, Class clazz) throws Exception {
        DbUtil db=new DbUtil();
        ResultSet resultSet=db.queryCallHandle(callSql);
        IResultSetHandler rh=new ResultSetHandler(clazz);
        List<T> resultList= (List<T>) rh.handleList(resultSet);
        return resultList;
    }


}
